package util;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import systemconfig.SystemConfiguration;
import exceptions.CannotSendMailException;

public class MailSender {
    // Sends a mail from a Gmail account

    // ---------INSTANCE VARIABLES-----------------------------------------//

    private String senderAdress;

    private String senderPassword;

    // ---------CONSTRUCTORS------------------------------------------------//

    public MailSender() {
        this.senderAdress = SystemConfiguration.getInstance().getMailSenderAdress();
        this.senderPassword = SystemConfiguration.getInstance().getMailSenderPassword();
    }

    // ---------OTHER BEHAVIOR---------------------------------------------//

    public Session prepareSession() {
        Properties props = new Properties();

        // Nombre del host de correo, es smtp.gmail.com
        props.setProperty("mail.smtp.host", "smtp.gmail.com");

        // TLS si está disponible
        props.setProperty("mail.smtp.starttls.enable", "true");

        // Puerto de gmail para envio de correos
        props.setProperty("mail.smtp.port", "587");

        // Nombre del usuario
        props.setProperty("mail.smtp.user", this.senderAdress);

        // Si requiere o no usuario y password para conectarse.
        props.setProperty("mail.smtp.auth", "true");

        Session session = Session.getDefaultInstance(props);
        session.setDebug(true); // Cuando funcione lo saco

        return session;
    }

    // -----------//

    public MimeMessage prepareDefaultMail(final Session aSession, final String aRecipient) throws AddressException,
            MessagingException {
        MimeMessage message = new MimeMessage(aSession);
        message.setFrom(new InternetAddress(this.senderAdress));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(aRecipient));

        return message;

    }

    public void addContentsToDefaultedMail(final MimeMessage target, final String aSubject, final String aText)
            throws MessagingException {
        // PRECONDITION: prepareDefaultMail already called over target
        target.setSubject(aSubject);
        target.setText(aText);
    }

    public void sendPreparedMail(final Session aSession, final MimeMessage aMessage) throws MessagingException {
        Transport transport = aSession.getTransport("smtp");
        transport.connect(this.senderAdress, this.senderPassword);
        transport.sendMessage(aMessage, aMessage.getAllRecipients());
        transport.close();
    }

    // ------------------------------------------//
    // ---------MAIN METHOD---------------------//
    // ------------------------------------------//

    public void sendMail(final String recipient, final String aSubject, final String aText) {
        try {
            Session session = this.prepareSession();
            MimeMessage mail = this.prepareDefaultMail(session, recipient);
            this.addContentsToDefaultedMail(mail, aSubject, aText);
            this.sendPreparedMail(session, mail);
        } catch (AddressException e) {
            throw new CannotSendMailException(" Problem with the mail recipient adress:" + recipient, e);
        } catch (MessagingException e) {
            throw new CannotSendMailException("Problem sending mail to" + recipient, e);
        }
    }

    public String getSenderAdress() {
        return this.senderAdress;
    }

    public void setSenderAdress(final String senderAdress) {
        this.senderAdress = senderAdress;
    }

    public String getSenderPassword() {
        return this.senderPassword;
    }

    public void setSenderPassword(final String senderPassword) {
        this.senderPassword = senderPassword;
    }

}
